

module HLibcell.IO (hmesh_read_array,
    hmesh_read_cell,
    htest_io,
    hprint_mesh)where
import HLibcell.HFunc
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as VM
import Control.Monad.Primitive
import Data.List
import qualified Data.Map.Lazy as HMap
import qualified Data.IntMap.Lazy as IMap
-- import Data.Text.Read 
-- import Data.Text

import System.IO

hmesh_read_array::V.Vector (V.Vector Double)->V.Vector (V.Vector Int)->V.Vector (V.Vector Int)->Int->Bool->HMesh m v hf f c
hmesh_read_array vs hfs cs mdim sim=if length hfs==0
    then 
        myfun3 cs 0 $ myfun vs 0 mesh
    else 
        myfun2 cs 0 $myfun1 hfs 0 $ myfun vs 0 mesh
    where
        myfun::V.Vector (V.Vector Double)->Int->HMesh m v hf f c->HMesh m v hf f c 
        myfun vs1 i mesh1=if length vs1<=i
            then 
                mesh1
            else 
               myfun vs1 (i+1)  $ fst  $hmesh_create_vertexv (V.toList $ vs1 V.! i) mesh1

        myfun1::V.Vector (V.Vector Int)->Int->HMesh m v hf f c->HMesh m v hf f c 
        myfun1 hfs1 i mesh1 =if length hfs1 <= i || f==Nothing 
            then 
                mesh1
            else 
                myfun1 hfs1 (i+1) $ mesh3 
            where
                vs2=V.toList $ hfs1 V.! i
                (mesh2,f)=hmesh_create_facevi vs2 mesh1
                (mesh3 ,hf)=hmesh_create_halffacei (hface_get_id $ (\(Just x)->x) f) vs2 mesh2

        myfun2::V.Vector (V.Vector Int)->Int ->HMesh m v hf f c ->HMesh m v hf f c 
        myfun2 cs1 i mesh1=if length cs1 <= i 
            then 
                mesh1 
            else 
                myfun2 cs1 (i+1) $fst$ hmesh_create_cellfi (V.toList $ cs1 V.! i) mesh1 
        myfun3::V.Vector (V.Vector Int)->Int ->HMesh m v hf f c ->HMesh m v hf f c 
        myfun3 cs1 i mesh1=if length cs1 <= i 
            then 
                mesh1 
            else 
                myfun3 cs1 (i+1) $fst$ hmesh_create_cellvi (V.toList $ cs1 V.! i) mesh1 
        mesh=hmesh_replace_simplex sim .hmesh_replace_dimension mdim$ hmesh_create



hmesh_read_cell::String->IO (HMesh m v hf f c)
hmesh_read_cell filename=myreadcell filename
    where
        myreadcell::String->IO (HMesh m v hf f c)
        myreadcell filename1=do
            h<-openFile filename1 ReadMode
            cell<-hGetLine h
            putStrLn cell
            (nums1,nums2,nums3,bdim,mdim,sim) <- get_header_info h
            putStrLn "zheli libo "
            putStrLn $show (nums1,nums2,nums3,bdim,mdim,sim)

            vs<- get_vertices_vector (nums1,bdim) h
            -- putStrLn "zhongjian1 "
           -- putStrLn $ show $ v V.! 1
            --putStrLn $show nums2
            vs1<-get_halffaces_vector  nums2 h
            --putStrLn $ show $ (v1 V.!2) V.! 1
            vs2<-get_cells_vector nums3 h

            --putStrLn "zhongjian "
            --putStrLn $ show $ (v2 V.! 1) V.! 3 
            return $ hmesh_read_array vs vs1 vs2 mdim sim 

        get_header_info::Handle->IO (Int,Int,Int,Int,Int,Bool)
        get_header_info h =do
            bdim<-  (  return.read.(\x->(words x)!!1) =<<hGetLine h):: IO Int
            putStrLn $show bdim
            mdim<- return .read. (\x->(words x)!!1)=<<hGetLine h :: IO Int 
            putStrLn $show mdim
            sim1<- return .read.(\x->(words x)!!1)=<< hGetLine h:: IO Int
            
            num<- hGetLine h
            nums<- return $ words num 
            return ((read $nums!!0 ::Int),(read $ nums !!1::Int),(read $ nums!!2::Int),
                bdim,mdim,(\x->if x==0 then False else True) sim1) 

        get_vertices_vector::(Int, Int)->Handle->IO(V.Vector (V.Vector Double)) 
        get_vertices_vector (num,bdim) h =do 
            v1<-VM.new num
            my_fun 0 v1 h 
            V.freeze v1
            where
                my_cur::VM.MVector (PrimState IO) Double->[Double]->Int->IO()
                my_cur _ [] _ =return ()
                my_cur vpp (x:xs) nn =do 
                    VM.write vpp nn x
                    my_cur vpp xs (nn+1) 
                my_one::Int->Handle->VM.MVector (PrimState IO) (V.Vector Double)->IO()
                my_one nn hh pp=do 
                    s<-hGetLine hh 
                    --lpp <- return $ map read (words s)::IO ([Int])
                    vpp<- VM.new bdim
                    my_cur vpp (map read (words s)::[Double]) 0
                    vpp1<-V.freeze vpp
                    VM.write pp nn vpp1
                my_fun::Int ->VM.MVector (PrimState IO) (V.Vector Double)->Handle->IO()
                my_fun nn1 pp1 hh1=if nn1>= num 
                    then return ()
                    else 
                        do 
                            my_one nn1 hh1 pp1
                            my_fun (nn1+1) pp1 hh1 

        get_halffaces_vector::Int->Handle->IO (V.Vector (V.Vector Int))
        get_halffaces_vector 0 h =return $ V.empty::IO (V.Vector (V.Vector Int))
        get_halffaces_vector num h =do
            hf1<- VM.new num
            my_fun 0 hf1 h  
            V.freeze hf1
            where 
                my_cur::VM.MVector (PrimState IO) Int->[Int]->Int->IO()
                my_cur _ [] _ =return ()
                my_cur vv (x:xs) nn =do 
                    VM.write  vv nn x
                    my_cur vv xs (nn+1) 
                my_one::Int->Handle->VM.MVector (PrimState IO) (V.Vector Int)->IO()
                my_one nn hh vv=do 
                    s<-hGetLine hh 
                    ii <- return $ map read (words s)::IO ([Int])
                    hfids<- VM.new (head ii) 
                    my_cur hfids (tail ii) 0
                    vv1<-V.freeze hfids
                    VM.write vv nn vv1
                my_fun::Int ->VM.MVector (PrimState IO) (V.Vector Int)->Handle->IO()
                my_fun nn1 vv1 hh1=if nn1>= num 
                    then return ()
                    else 
                        do 
                            my_one nn1 hh1 vv1
                            my_fun (nn1+1) vv1 hh1 

        get_cells_vector::Int->Handle->IO (V.Vector (V.Vector Int))
        get_cells_vector num h=get_halffaces_vector num h 
 


htest_io::String->IO()
htest_io filename= do
    let 
        get_header_info::Handle->IO (Int,Int,Int,Int,Int,Int)
        get_header_info h =do
            bdim<-  (  return.read.(\x->(words x)!!1) =<<hGetLine h)
            mdim<- return .read. (\x->(words x)!!1)=<<hGetLine h 
            sim<- return .read.(\x->(words x)!!1)=<< hGetLine h
            num<- hGetLine h
            nums<- return $ words num 
            return ((read $nums!!0 ::Int),(read $ nums !!1::Int),(read $ nums!!2::Int),bdim,mdim,sim) 

        get_vertices_vector::(Int, Int)->Handle->IO(V.Vector (V.Vector Double)) 
        get_vertices_vector (num,bdim) h =do 
            v<-VM.new num
            my_fun 0 v h 
            V.freeze v
            where
                my_cur::VM.MVector (PrimState IO) Double->[Double]->Int->IO()
                my_cur _ [] _ =return ()
                my_cur vpp (x:xs) nn =do 
                    VM.write vpp nn x
                    my_cur vpp xs (nn+1) 
                my_one::Int->Handle->VM.MVector (PrimState IO) (V.Vector Double)->IO()
                my_one nn hh pp=do 
                    s<-hGetLine hh 
                    vpp<- VM.new bdim
                    my_cur vpp (map read (words s)::[Double]) 0
                    vpp1<-V.freeze vpp
                    VM.write pp nn vpp1
                my_fun::Int ->VM.MVector (PrimState IO) (V.Vector Double)->Handle->IO()
                my_fun nn1 pp1 hh1=if nn1>= num 
                    then return ()
                    else 
                        do 
                            my_one nn1 hh1 pp1
                            my_fun (nn1+1) pp1 hh1 


        get_halffaces_vector::Int->Handle->IO (V.Vector (V.Vector Int))
        get_halffaces_vector 0 h =return $ V.empty::IO (V.Vector (V.Vector Int))
        get_halffaces_vector num h =do
            hf1<- VM.new num
            my_fun 0 hf1 h  
            V.freeze hf1
            where 
                my_cur::VM.MVector (PrimState IO) Int->[Int]->Int->IO()
                my_cur _ [] _ =return ()
                my_cur vv (x:xs) nn =do 
                    VM.write  vv nn x
                    my_cur vv xs (nn+1) 
                my_one::Int->Handle->VM.MVector (PrimState IO) (V.Vector Int)->IO()
                my_one nn hh vv=do 
                    s<-hGetLine hh 
                    ii <- return $ map read (words s)::IO ([Int])
                    hfids<- VM.new (head ii) 
                    my_cur hfids (tail ii) 0
                    vv1<-V.freeze hfids
                    VM.write vv nn vv1
                my_fun::Int ->VM.MVector (PrimState IO) (V.Vector Int)->Handle->IO()
                my_fun nn1 vv1 hh1=if nn1>= num 
                    then return ()
                    else 
                        do 
                            my_one nn1 hh1 vv1
                            my_fun (nn1+1) vv1 hh1 

        get_cells_vector::Int->Handle->IO (V.Vector (V.Vector Int))
        get_cells_vector num h=get_halffaces_vector num h 



        test::Handle->IO ()
        test h =do
            (nums1,nums2,nums3,bdim,mdim,sim) <- get_header_info h
            --putStrLn $show (nums1,bdim)
            v<- get_vertices_vector (nums1,bdim) h
            putStrLn $ show $ v V.! 1
            putStrLn $show nums2
            v1<-get_halffaces_vector  nums2 h
            putStrLn $ show $ (v1 V.!2) V.! 1
            v2<-get_cells_vector nums3 h
            putStrLn $ show $ (v2 V.! 1) V.! 3
            return ()
    h1<- openFile filename ReadMode
    cell<- hGetLine h1
    test h1  
    return ()  



hprint_mesh::HMesh m v hf f c->IO()
hprint_mesh  mesh =do
    putStrLn "Vertices"
    IMap.foldr hshow_vertices (return ()) $hmesh_get_vertices mesh 
    putStrLn "Faces"
    IMap.foldr hshow_faces (return ()) $hmesh_get_faces mesh
    putStrLn "Cells"
    IMap.foldr hshow_cells (return ()) $hmesh_get_cells mesh 
    where
        hshow_vertices::HVertex v->IO()->IO ()
        hshow_vertices ver io=do  
            putStr $(show $ hvertex_get_id ver)++ "  "
            putStrLn $ show $ hvertex_get_point ver
            io
        hshow_faces::HFace f->IO()->IO()
        hshow_faces fac io =do 
            putStr $ (show $ hface_get_id fac) ++ "  "
            putStrLn $ show $ hface_get_vertices fac 
            io
        hshow_cells::HCell c->IO ()->IO ()
        hshow_cells ce io =do
            putStr $ (show $ hcell_get_id ce) ++ "  "
            putStr $ (show $ hcell_get_vertices ce )++ " "
            putStrLn $ (show $hcell_get_halffaces ce)
            io  
